/**
 * Copyright © 2016-2025 The Thingsboard Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.terracloud.server.service.log;

import com.terracloud.server.common.data.id.DeviceId;
import com.terracloud.server.common.data.id.EntityId;
import com.terracloud.server.common.data.id.TenantId;
import com.terracloud.server.common.data.id.UserId;
import com.terracloud.server.common.data.log.LogLevel;
import com.terracloud.server.common.data.log.LogType;
import com.terracloud.server.common.data.log.PlatformLog;
import com.terracloud.server.common.data.log.TerminalLog;
import com.terracloud.server.common.data.id.TerminalLogId;
import com.terracloud.server.common.data.id.PlatformLogId;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.UUID;

/**
 * 统一日志服务默认实现
 * 实现日志记录功能，将日志保存到数据库
 */
@Service
@Slf4j
public class DefaultUnifiedLogService implements UnifiedLogService {
    
    @Autowired
    private TerminalLogService terminalLogService;
    
    @Autowired
    private PlatformLogService platformLogService;
    
    @Override
    public void logTerminal(DeviceId deviceId, LogType logType, LogLevel logLevel, String content,
                            TenantId tenantId, UserId userId) {
        logTerminal(deviceId, logType, logLevel, content, tenantId, userId, null);
    }
    
    @Override
    public void logTerminal(DeviceId deviceId, LogType logType, LogLevel logLevel, String content,
                            TenantId tenantId, UserId userId, String additionalInfo) {
        try {
            TerminalLog terminalLog = new TerminalLog();
            terminalLog.setId(new TerminalLogId(UUID.randomUUID()));
            terminalLog.setDeviceId(deviceId);
            terminalLog.setLogType(logType);
            terminalLog.setLogLevel(logLevel);
            terminalLog.setContentSummary(content);
            terminalLog.setContentDetails(additionalInfo);
            terminalLog.setTenantId(tenantId);
            if (userId != null) {
                terminalLog.setProcessor(userId.toString());
            }
            terminalLog.setCreatedTime(new Date().getTime());
            terminalLog.setOccurTime(new Date().getTime());
            
            // 保存到数据库
            terminalLogService.saveTerminalLog(terminalLog);
            log.debug("Successfully saved terminal log: deviceId={}, logType={}, content={}", deviceId, logType, content);
        } catch (Exception e) {
            log.error("Failed to save terminal log: deviceId={}, logType={}, content={}, error={}", 
                     deviceId, logType, content, e.getMessage(), e);
        }
    }
    
    @Override
    public void logTerminal(TerminalLog terminalLog) {
        try {
            // 确保ID存在
            if (terminalLog.getId() == null) {
                terminalLog.setId(new TerminalLogId(UUID.randomUUID()));
            }
            
            // 确保创建时间存在
            if (terminalLog.getCreatedTime() == 0L) {
                terminalLog.setCreatedTime(new Date().getTime());
            }
            
            // 确保发生时间存在
            if (terminalLog.getOccurTime() == null) {
                terminalLog.setOccurTime(new Date().getTime());
            }
            
            // 保存到数据库
            terminalLogService.saveTerminalLog(terminalLog);
            log.debug("Successfully saved terminal log: deviceId={}, logType={}", 
                     terminalLog.getDeviceId(), terminalLog.getLogType());
        } catch (Exception e) {
            log.error("Failed to save terminal log: deviceId={}, logType={}, error={}", 
                     terminalLog.getDeviceId(), terminalLog.getLogType(), e.getMessage(), e);
        }
    }
    
    @Override
    public void logPlatform(LogType logType, LogLevel logLevel, String content,
                            TenantId tenantId, UserId userId) {
        logPlatform(logType, logLevel, content, tenantId, userId, null);
    }
    
    @Override
    public void logPlatform(LogType logType, LogLevel logLevel, String content,
                            TenantId tenantId, UserId userId, String additionalInfo) {
        try {
            PlatformLog platformLog = new PlatformLog();
            platformLog.setId(new PlatformLogId(UUID.randomUUID()));
            platformLog.setLogType(logType);
            platformLog.setLogLevel(logLevel);
            platformLog.setOperationContent(content);
            platformLog.setOperationDetails(additionalInfo);
            platformLog.setTenantId(tenantId);
            platformLog.setUserId(userId);
            platformLog.setCreatedTime(new Date().getTime());
            platformLog.setOccurTime(new Date().getTime());
            
            // 保存到数据库
            platformLogService.savePlatformLog(platformLog);
            log.debug("Successfully saved platform log: logType={}, content={}", logType, content);
        } catch (Exception e) {
            log.error("Failed to save platform log: logType={}, content={}, error={}", 
                     logType, content, e.getMessage(), e);
        }
    }
    
    @Override
    public void logPlatform(PlatformLog platformLog) {
        try {
            // 确保ID存在
            if (platformLog.getId() == null) {
                platformLog.setId(new PlatformLogId(UUID.randomUUID()));
            }
            
            // 确保创建时间存在
            if (platformLog.getCreatedTime() == 0L) {
                platformLog.setCreatedTime(new Date().getTime());
            }
            
            // 确保发生时间存在
            if (platformLog.getOccurTime() == null) {
                platformLog.setOccurTime(new Date().getTime());
            }
            
            // 保存到数据库
            platformLogService.savePlatformLog(platformLog);
            log.debug("Successfully saved platform log: logType={}", platformLog.getLogType());
        } catch (Exception e) {
            log.error("Failed to save platform log: logType={}, error={}", 
                     platformLog.getLogType(), e.getMessage(), e);
        }
    }
    
    @Override
    public void log(EntityId entityId, LogType logType, LogLevel logLevel, String content,
                    TenantId tenantId, UserId userId) {
        log(entityId, logType, logLevel, content, tenantId, userId, null);
    }
    
    @Override
    public void log(EntityId entityId, LogType logType, LogLevel logLevel, String content,
                    TenantId tenantId, UserId userId, String additionalInfo) {
        // 根据实体类型决定记录哪种日志
        if (entityId instanceof DeviceId) {
            logTerminal((DeviceId) entityId, logType, logLevel, content, tenantId, userId, additionalInfo);
        } else {
            logPlatform(logType, logLevel, content, tenantId, userId, additionalInfo);
        }
    }
    
    @Override
    public void log(LogType logType, LogLevel logLevel, String content) {
        // 记录为平台日志，使用系统租户ID
        logPlatform(logType, logLevel, content, TenantId.SYS_TENANT_ID, null);
    }
}